-
Notifications
You must be signed in to change notification settings - Fork 7
VPLAY-12213: ABR Refactoring part 3 - encapsulate remaining abr logic #901
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev_sprint_25_2
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request refactors ABR (Adaptive Bitrate) logic by encapsulating bandwidth estimation into a pluggable architecture. The changes move bandwidth tracking from PrivateInstanceAAMP into ABRManager and introduce a BandwidthEstimatorBase interface with two implementations: RMOBandwidthEstimator (legacy algorithm) and HarmonicEWMAEstimator (new algorithm).
Changes:
- Introduced
BandwidthEstimatorBaseinterface and two concrete implementations for bandwidth estimation algorithms - Moved bandwidth state management from
PrivateInstanceAAMPtoABRManager - Updated all callers to use
ABRManagermethods instead of directPrivateInstanceAAMPmethods - Added configuration option to select bandwidth estimator type
- Updated tests and fakes to reflect the new architecture
Reviewed changes
Copilot reviewed 29 out of 29 changed files in this pull request and generated 15 comments.
Show a summary per file
| File | Description |
|---|---|
| abr/BandwidthEstimatorBase.h | New base interface for bandwidth estimator implementations |
| abr/RMOBandwidthEstimator.h/cpp | Legacy Rolling Median Outlier bandwidth estimation algorithm extracted from ABR code |
| abr/HarmonicEWMAEstimator.h/cpp | New Harmonic EWMA bandwidth estimation algorithm (renamed from NetworkBandwidthEstimator) |
| abr/abr.h/cpp | Extended ABRManager with bandwidth estimator management and state tracking |
| priv_aamp.h/cpp | Removed bandwidth state members and delegated to ABRManager |
| streamabstraction.cpp | Updated to call ABRManager methods; added persist bandwidth logic |
| fragmentcollector_hls.cpp/mpd.cpp | Updated to use ABRManager bandwidth methods |
| AampDefine.h/AampConfig.h/cpp | Added BandwidthEstimatorType enum and configuration option |
| test/utests/tests/*/CMakeLists.txt | Added new source files to test builds |
| test/utests/tests/PrivAampTests/PrivAampTests.cpp | Updated tests to use ABRManager interface |
| test/utests/tests/NetworkBandwidthEstimator/ | Renamed to HarmonicEWMAEstimator; added progress update test |
| test/utests/fakes/ | Updated fakes to remove deprecated methods |
streamabstraction.cpp
Outdated
| if(ISCONFIGSET(eAAMPConfig_PersistLowNetworkBandwidth)||ISCONFIGSET(eAAMPConfig_PersistHighNetworkBandwidth)) | ||
| { | ||
| if(networkBandwidth > 0 && aamp->mbPlayEnabled) | ||
| { | ||
| ABRManager::setPersistBandwidth(networkBandwidth); | ||
| ABRManager::mPersistBandwidthUpdatedTime = aamp_GetCurrentTimeMS(); | ||
| } | ||
| } |
Copilot
AI
Jan 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This persist bandwidth logic is duplicated in multiple places within streamabstraction.cpp (lines 2585-2592, 2703-2710, 2959-2966, 2997-3004). The exact same code block appears four times. This violates the DRY principle and makes maintenance difficult. Consider extracting this logic into a helper method in ABRManager (e.g., UpdatePersistBandwidthIfNeeded) that can be called from these locations.
streamabstraction.cpp
Outdated
| if(ISCONFIGSET(eAAMPConfig_PersistLowNetworkBandwidth)||ISCONFIGSET(eAAMPConfig_PersistHighNetworkBandwidth)) | ||
| { | ||
| if(stAbrInfo.networkBandwidth > 0 && aamp->mbPlayEnabled) | ||
| { | ||
| ABRManager::setPersistBandwidth(stAbrInfo.networkBandwidth); | ||
| ABRManager::mPersistBandwidthUpdatedTime = aamp_GetCurrentTimeMS(); | ||
| } | ||
| } |
Copilot
AI
Jan 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The persist bandwidth logic is also duplicated here. This is the same code as appears on lines 2585-2592. Consider consolidating this duplication by extracting it into a helper method.
a93313d to
8bc0a11
Compare
8bc0a11 to
98ecf34
Compare
… inside abr.cpp Reason for change: To encapsulate all ABR related logic inside abr.cpp and abr.h. This will help in future to add/remove different bandwidth estimation algorithms without affecting other parts of the code. Risks: Low Test Procedure: Test with Linear and VOD Priority: P1 Signed-off-by: Nandakishor U M <nu641001@gmail.com>
98ecf34 to
cdf73de
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 27 out of 27 changed files in this pull request and generated 4 comments.
| #include <mutex> | ||
| #include "AampMediaType.h" | ||
| #include "BandwidthEstimatorBase.h" | ||
| class BandwidthEstimatorBase; |
Copilot
AI
Jan 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant forward declaration. Line 33 contains a forward declaration of BandwidthEstimatorBase, but line 32 already includes the full header file BandwidthEstimatorBase.h. The forward declaration should be removed as it's unnecessary and could cause confusion.
| class BandwidthEstimatorBase; |
| void ABRManager::ResetCurrentlyAvailableBandwidth() | ||
| { | ||
| std::lock_guard<std::mutex> lock(mBandwidthEstimatorLock); | ||
| mBandwidthEstimator->ResetCurrentlyAvailableBandwidth(); |
Copilot
AI
Jan 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential null pointer dereference. The function calls mBandwidthEstimator->ResetCurrentlyAvailableBandwidth() without checking if mBandwidthEstimator is null. While the estimator is initialized in the constructor, there could be edge cases where it's null. Additionally, HarmonicEWMAEstimator doesn't override ResetCurrentlyAvailableBandwidth(), which means when using that estimator, this call will invoke the base class's no-op implementation and fail to actually reset the bandwidth state. Consider adding a null check and ensuring HarmonicEWMAEstimator properly implements this method.
| mBandwidthEstimator->ResetCurrentlyAvailableBandwidth(); | |
| if (mBandwidthEstimator) | |
| { | |
| mBandwidthEstimator->ResetCurrentlyAvailableBandwidth(); | |
| } |
| BandwidthEstimatorConfig config; | ||
| config.mAbrCacheLife = eAAMPAbrConfig.abrCacheLife; | ||
| config.mAbrCacheLength = eAAMPAbrConfig.abrCacheLength; | ||
| config.mAbrCacheOutlier = eAAMPAbrConfig.abrCacheOutlier; | ||
| config.mLowLatencyCacheLength = DEFAULT_ABR_CHUNK_CACHE_LENGTH; | ||
| mBandwidthEstimator.reset(new RMOBandwidthEstimator(config)); |
Copilot
AI
Jan 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Configuration initialization issue. When SetBandwidthEstimatorType is called from the constructor (line 59), it accesses eAAMPAbrConfig members (abrCacheLife, abrCacheLength, abrCacheOutlier) that haven't been initialized yet, as ReadPlayerConfig() hasn't been called. These will all be zero due to default initialization. This means the RMOBandwidthEstimator will be created with all-zero configuration values initially, which may not represent the correct default behavior. Consider either: 1) Using explicit default constants instead of relying on eAAMPAbrConfig in the constructor path, or 2) Deferring estimator creation until after configuration is loaded.
| public: | ||
| HarmonicEWMAEstimator() = default; | ||
|
|
||
| const char *GetNetworkEstimatorName() const override; | ||
| void Reset() override; | ||
| void AddBandwidthSample(BitsPerSecond downloadbps, bool lowLatencyMode) override; | ||
| void UpdateDownloadMetrics(const DownloadMetrics &curl) override; | ||
| void UpdateDownloadProgress(const DownloadProgressInfo &progressInfo) override; | ||
| BitsPerSecond GetBandwidthBitsPerSecond() override; | ||
| double GetThroughputBytesPerSecond() override; | ||
| double GetTimeToFirstByteSeconds() override; | ||
| double GetPredictedDownloadTimeSeconds(std::size_t segment_size_bytes) override; | ||
| }; |
Copilot
AI
Jan 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing override of ResetCurrentlyAvailableBandwidth(). The HarmonicEWMAEstimator class doesn't override the ResetCurrentlyAvailableBandwidth() method from BandwidthEstimatorBase. This means when ABRManager::ResetCurrentlyAvailableBandwidth() is called (which happens during profile rampdown in streamabstraction.cpp), it will invoke the base class's no-op implementation and fail to actually reset the bandwidth estimation state. This could lead to incorrect ABR decisions. Consider adding an override that clears the appropriate internal state (m_history, EWMA values, etc.).
Reason for change: To encapsulate all ABR related logic inside abr.cpp and abr.h. This will help in future to add/remove different bandwidth estimation algorithms without affecting other parts of the code.
Risks: Low
Test Procedure: Test with Linear and VOD
Priority: P1